﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Evpo.ContactData.Common;
using System.Data.SqlClient;
using System.Data;

namespace Evpo.ContactData.Data
{
    public class ContactAdapter : AdapterBase
    {
        public ContactAdapter(Connection connection) : base(connection) { }

        #region Fields
        #endregion

        #region Properties
        protected override string PrimaryKeyField
        {
            get { return Fields.ContactID; }
        }

        protected override string SProcToDelete
        {
            get { return SProcs.DeleteContact; }
        }

        protected override string SProcToSave
        {
            get { return SProcs.SaveContact; }
        }

        protected override string SProcToLoad
        {
            get { return SProcs.GetContact; }
        }

        protected override string SProcToQuery
        {
            get { return SProcs.GetContacts; }
        }
        #endregion

        #region Methods

        public List<Contact> GetContactsByAddressID(int addressID)
        {
            List<Contact> retVal = new List<Contact>();

            FillFromQuery<Contact>(
                new List<SqlParameter>() { new SqlParameter("@ContactAddressID", addressID), },
                retVal,
                SProcs.GetAddressResidents);

            return retVal;
        }

        public void Save(Contact contact, bool isNew)
        {
            Save<Contact>(contact, isNew);
        }

        public List<Contact> QueryContacts(ContactQueryParameters queryParameters, out int contactCount)
        {
            contactCount = -1;

            var contactCountParam =
                new SqlParameter("@ContactCount", SqlDbType.Int)
                {
                    Direction = ParameterDirection.Output
                };

            var parameters = new List<SqlParameter>()
            {
                contactCountParam,
            };

            if (queryParameters.SortField == ContactSortFields.FirstName)
                parameters.Add(new SqlParameter("@SortByFirstName", true));

            if (queryParameters.SortField == ContactSortFields.LastName)
                parameters.Add(new SqlParameter("@SortByLastName", true));

            if (queryParameters.PageBegin.HasValue)
                parameters.Add(new SqlParameter("@PageBegin", queryParameters.PageBegin.Value));

            if (queryParameters.PageEnd.HasValue)
                parameters.Add(new SqlParameter("@PageEnd", queryParameters.PageEnd.Value));

            if (!String.IsNullOrEmpty(queryParameters.FirstNameContains))
                parameters.Add(new SqlParameter("@FirstNameContains", queryParameters.FirstNameContains));

            if (!String.IsNullOrEmpty(queryParameters.LastNameContains))
                parameters.Add(new SqlParameter("@LastNameContains", queryParameters.LastNameContains));

            var retList = new List<Contact>();

            FillFromQuery<Contact>(parameters, retList);

            contactCount = (int)contactCountParam.Value;
            return retList;
        }


        public Contact Load(int contactID)
        {
            return Load<Contact>(contactID);
        }

        internal static void FillContactParametersToSave(Contact contact, List<SqlParameter> paramList)
        {
            if (paramList == null)
                throw new ArgumentNullException("paramList");

            paramList.Add(new SqlParameter("@" + Fields.TitleID, contact.TitleID));
            paramList.Add(new SqlParameter("@" + Fields.FirstName, contact.FirstName));
            paramList.Add(new SqlParameter("@" + Fields.LastName, contact.LastName));
            paramList.Add(new SqlParameter("@" + Fields.IsMale, contact.IsMale));
            paramList.Add(new SqlParameter("@" + Fields.Email, contact.Email));
            paramList.Add(new SqlParameter("@" + Fields.HomePhone, contact.HomePhone));
            paramList.Add(new SqlParameter("@" + Fields.MobilePhone, contact.MobilePhone));
            paramList.Add(new SqlParameter("@" + Fields.BusinessPhone, contact.BusinessPhone));
            paramList.Add(new SqlParameter("@" + Fields.IsDeceased, contact.IsDeceased));
            
            paramList.Add(new SqlParameter("@" + Fields.AddressID, 
                contact.AddressID.HasValue ? (object)contact.AddressID.Value : DBNull.Value));

            paramList.Add(new SqlParameter("@" + Fields.DateOfBirth, 
                contact.DateOfBirth.HasValue ? (object) contact.DateOfBirth.Value : DBNull.Value));

            paramList.Add(new SqlParameter("@" + Fields.MaritalStatus, contact.MaritalStatus));
            paramList.Add(new SqlParameter("@" + Fields.HomeTown, contact.HomeTown));
            paramList.Add(new SqlParameter("@" + Fields.MembershipType, contact.MembershipType));
            paramList.Add(new SqlParameter("@" + Fields.PrimaryMailRecipient, contact.PrimaryMailRecipient));
            paramList.Add(new SqlParameter("@" + Fields.MailFormat, contact.MailFormat));
            paramList.Add(new SqlParameter("@" + Fields.ContactInterest, contact.ContactInterest));
        }

        internal static void FillFieldsFromReader(Contact contact, ProcedureOutputReader procReader)
        {
            contact.ContactID = procReader.GetID(Fields.ContactID);
            contact.TitleID = procReader.GetID(Fields.TitleID);
            contact.FirstName = procReader.GetString(Fields.FirstName);
            contact.LastName = procReader.GetString(Fields.LastName);
            contact.IsMale = procReader.GetBoolean(Fields.IsMale);
            contact.Email = procReader.GetString(Fields.Email);
            contact.HomePhone = procReader.GetString(Fields.HomePhone);
            contact.MobilePhone = procReader.GetString(Fields.MobilePhone);
            contact.BusinessPhone = procReader.GetString(Fields.BusinessPhone);
            contact.IsDeceased = procReader.GetBoolean(Fields.IsDeceased);
         
            contact.AddressID = !procReader.IsDBNull(Fields.AddressID) ?
                (int?)procReader.GetID(Fields.AddressID) : null;
            
            contact.DateOfBirth = !procReader.IsDBNull(Fields.DateOfBirth) ?
                (DateTime?)procReader.GetDateTime(Fields.DateOfBirth) : null;

            contact.MaritalStatus = procReader.GetID(Fields.MaritalStatus);
            contact.HomeTown = procReader.GetID(Fields.HomeTown);
            contact.MembershipType = procReader.GetID(Fields.MembershipType);
            contact.PrimaryMailRecipient = procReader.GetBoolean(Fields.PrimaryMailRecipient);
            contact.MailFormat = procReader.GetID(Fields.MailFormat);
            contact.ContactInterest = procReader.GetID(Fields.ContactInterest);
        }
        #endregion Methods

        #region Classes
        private class Fields
        {
            internal const string TitleID = "TitleID";
            internal const string FirstName = "FirstName";
            internal const string LastName = "LastName";
            internal const string ContactID = "ContactID";
            internal const string IsMale = "IsMale";
            internal const string Email = "Email";
            internal const string HomePhone = "HomePhone";
            internal const string MobilePhone = "MobilePhone";
            internal const string BusinessPhone = "BusinessPhone";
            internal const string IsDeceased = "IsDeceased";
            internal const string AddressID = "AddressID";
            internal const string DateOfBirth = "DateOfBirth";
            internal const string MaritalStatus = "MaritalStatus";
            internal const string HomeTown = "HomeTown";
            internal const string MembershipType = "MembershipType";
            internal const string PrimaryMailRecipient = "PrimaryMailRecipient";
            internal const string MailFormat = "MailFormat";
            internal const string ContactInterest = "ContactInterest";
        }
        #endregion

        
    }
}
